package sk.vrto.web.presenters;

import com.google.common.eventbus.Subscribe;
import com.vaadin.ui.Component;
import sk.vrto.domain.Contact;
import sk.vrto.domain.User;
import sk.vrto.service.dao.ContactRepository;
import sk.vrto.web.base.Presenter;
import sk.vrto.web.events.ContactInsertedEvent;
import sk.vrto.web.events.ContactRemovedEvent;
import sk.vrto.web.events.ContactUpdatedEvent;
import sk.vrto.web.views.ContactView;
import sk.vrto.web.views.ContactsListView;

import java.util.Collection;
import java.util.Iterator;

public class ContactsListPresenter extends Presenter<ContactsListView> {

    private final ContactRepository contactRepository;
    private final User user;

    /**
     * @param contactRepository Repository for accessing contacts
     * @param user Logged user
     */
    public ContactsListPresenter(ContactRepository contactRepository, User user) {
        this.contactRepository = contactRepository;
        this.user = user;
    }

    /**
     * When contact is removed, then presenter finds its' corresponding view
     * and removes it from the list of remaining views.
     * @param e Triggering event
     */
    @Subscribe
    public void onContactRemoved(ContactRemovedEvent e) {
        String email = e.getRemovedContact();
        Iterator<Component> componentIterator = view.getComponentIterator();
        while (componentIterator.hasNext()) {
            ContactView contactView = (ContactView) componentIterator.next();
            if (contactView.getContact().getEmail().equals(email)) {
                this.view.removeComponent(contactView);
                break;
            }
        }
    }

    /**
     * When contact is updated, then presenter finds its' corresponding view,
     * removes it and creates new one.
     * @param e Triggering event
     */
    @Subscribe
    public void onContactUpdated(ContactUpdatedEvent e) {
        Contact contact = e.getUpdatedContact();
        Iterator<Component> componentIterator = view.getComponentIterator();
        while (componentIterator.hasNext()) {
            ContactView contactView = (ContactView) componentIterator.next();
            if (contactView.getContact().getEmail().equals(contact.getEmail())) {
                int index = view.getComponentIndex(contactView);
                view.removeComponent(contactView);
                view.addComponent(new ContactView(contact, e.getPresenterForNewView()), index);
                break;
            }
        }
    }

    /**
     * When contact is created, the presenter creates new view and puts
     * it to the list of other views.
     * @param e Triggering event
     */
    @Subscribe
    public void onContactInserted(ContactInsertedEvent e) {
        addContact(e.getNewContact());
    }

    /**
     * Creates list of contacts for the logged user.
     */
    public void loadAllContacts() {
        Collection<Contact> contacts = contactRepository.loadContatsForUser(user);
        for (Contact contact : contacts) {
            addContact(contact);
        }
    }

    private void addContact(Contact contact) {
        view.addContactItem(contact);
    }
}
